
#include "include.h"


const u32 u32CanId_Array[CANID_Number] = {CAN_UCPControlSignalCanID};

typedef union
{
	struct
	{
		u8  bReserved :1;
		u8  bRtr  :1;
		u8  bIde  :1;
	  u32 bExtend :18;
		u32 bStand :11;
	}bit;
	u32 all;
}CanFilter_Register;

static void CanIo_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	CAN_IO_ClockCmd();
	
	GPIO_InitStruct.GPIO_Pin = CAN_RX_IO;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(CAN_PORT,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Pin = CAN_TX_IO;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(CAN_PORT,&GPIO_InitStruct);
}


void Can_FilterListModeConfig(void)
{
	u8 u8FliterNumber = 0u;
	CAN_FilterInitTypeDef CAN_FilterInitStruct;
#if (CAN_FRAMETYPE == CAN_StandFRAME)
	u8FliterNumber = (u8)((CANID_Number>>2) + ((CANID_Number&0x3)?1:0));
	for(u8 u8number=0,CanID_ArrayIndex=0; u8number<u8FliterNumber; u8number++)
	{
		CAN_FilterInitStruct.CAN_FilterNumber = u8number;
		CAN_FilterInitStruct.CAN_FilterMode = CAN_FilterMode_IdList;
		CAN_FilterInitStruct.CAN_FilterScale = CAN_FilterScale_16bit;
		CAN_FilterInitStruct.CAN_FilterFIFOAssignment = CAN_FilterFIFO0;
		CAN_FilterInitStruct.CAN_FilterIdHigh = (u16)((u32CanId_Array[CanID_ArrayIndex++]<<5)&0xFFFF);
		if(CanID_ArrayIndex<CANID_Number)
		{
			CAN_FilterInitStruct.CAN_FilterIdLow  = (u16)((u32CanId_Array[CanID_ArrayIndex++]<<5)&0xFFFF);
		}
		else
		{
			CanID_ArrayIndex = 0;
			CAN_FilterInitStruct.CAN_FilterIdLow  = (u16)((u32CanId_Array[CanID_ArrayIndex++]<<5)&0xFFFF);
		}
    if(CanID_ArrayIndex<CANID_Number)
		{
			CAN_FilterInitStruct.CAN_FilterMaskIdHigh  = (u16)((u32CanId_Array[CanID_ArrayIndex++]<<5)&0xFFFF);
		}
		else
		{
			CanID_ArrayIndex = 0;
			CAN_FilterInitStruct.CAN_FilterMaskIdHigh  = (u16)((u32CanId_Array[CanID_ArrayIndex++]<<5)&0xFFFF);
		}
		if(CanID_ArrayIndex<CANID_Number)
		{
			CAN_FilterInitStruct.CAN_FilterMaskIdLow  = (u16)((u32CanId_Array[CanID_ArrayIndex++]<<5)&0xFFFF);
		}
		else
		{
			CanID_ArrayIndex = 0;
			CAN_FilterInitStruct.CAN_FilterMaskIdLow  = (u16)((u32CanId_Array[CanID_ArrayIndex++]<<5)&0xFFFF);
		}
		CAN_FilterInitStruct.CAN_FilterActivation = ENABLE;
		CAN_FilterInit(&CAN_FilterInitStruct);
	}
#endif
#if (CAN_FRAMETYPE == CAN_ExtendFRAME)
	u8FliterNumber = (u8)((CANID_Number>>1) + ((CANID_Number&0x1)?1:0));
	for(u8 u8number=0,CanID_ArrayIndex=0; u8number<u8FliterNumber; u8number++)
	{
		CAN_FilterInitStruct.CAN_FilterNumber = u8number;
		CAN_FilterInitStruct.CAN_FilterMode = CAN_FilterMode_IdList;
		CAN_FilterInitStruct.CAN_FilterScale = CAN_FilterScale_32bit;
		CAN_FilterInitStruct.CAN_FilterFIFOAssignment = CAN_FilterFIFO0;
		CAN_FilterInitStruct.CAN_FilterIdHigh = (u16)((u32CanId_Array[CanID_ArrayIndex]>>13)&0xFFFF);
		CAN_FilterInitStruct.CAN_FilterIdLow =  (u16)(((u32CanId_Array[CanID_ArrayIndex++]<<3)|0x04)&0xFFFF);
		if(CanID_ArrayIndex<CANID_Number)
		{
			CAN_FilterInitStruct.CAN_FilterMaskIdHigh  = (u16)((u32CanId_Array[CanID_ArrayIndex]>>13)&0xFFFF);
			CAN_FilterInitStruct.CAN_FilterMaskIdLow = (u16)(((u32CanId_Array[CanID_ArrayIndex++]<<3)|0x04)&0xFFFF);
		}
		else
		{
			CanID_ArrayIndex = 0;
			CAN_FilterInitStruct.CAN_FilterMaskIdHigh  = (u16)((u32CanId_Array[CanID_ArrayIndex]>>13)&0xFFFF);
			CAN_FilterInitStruct.CAN_FilterMaskIdLow = (u16)(((u32CanId_Array[CanID_ArrayIndex++]<<3)|0x04)&0xFFFF);
		}
		CAN_FilterInitStruct.CAN_FilterActivation = ENABLE;
		CAN_FilterInit(&CAN_FilterInitStruct);
	}
#endif
}

void Can_FilterMaskModeConfig(u8 u8Number,u8 u8FilterFifo,u32 CanMsgId)
{
	CAN_FilterInitTypeDef CAN_FilterInitStruct = {0};
	CanFilter_Register Filter_Register = {0};
	#if (CAN_FRAMETYPE == CAN_StandFRAME)
	  Filter_Register.all = (u32)(CanMsgId&0x7FF);
	#else
	  Filter_Register->all = (u32)(CanMsgId<<3);
	  Filter_Register->bit.bIde = 1;
	#endif
	CAN_FilterInitStruct.CAN_FilterNumber = u8Number;
	CAN_FilterInitStruct.CAN_FilterFIFOAssignment = u8FilterFifo;
	CAN_FilterInitStruct.CAN_FilterMode = CAN_FilterMode_IdMask;
	CAN_FilterInitStruct.CAN_FilterScale = CAN_FilterScale_32bit;
	CAN_FilterInitStruct.CAN_FilterIdHigh = (u16)((Filter_Register.all>>16)&0xFFFF);
	CAN_FilterInitStruct.CAN_FilterIdLow =  (u16)((Filter_Register.all>>0)&0xFFFF);
	#if (CAN_FILTER_MASK_MODE==CAN_Filter_Mask_IrrelevantMode)
  CAN_FilterInitStruct.CAN_FilterMaskIdHigh = 0x0000;
	CAN_FilterInitStruct.CAN_FilterMaskIdLow = 0x0000;
	#else
	 CAN_FilterInitStruct.CAN_FilterMaskIdHigh = 0xFFFF;
	 CAN_FilterInitStruct.CAN_FilterMaskIdLow =  0xFFFF;
	#endif
	CAN_FilterInitStruct.CAN_FilterActivation = ENABLE;
	CAN_FilterInit(&CAN_FilterInitStruct);
}

static void Nvic_CanConfig(void)
{
	NVIC_InitTypeDef NVIC_InitStruct;
	
	NVIC_InitStruct.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStruct);
}


void Can_Config(void)
{
	u8 u8NTq = 0u;
	CAN_InitTypeDef CAN_InitStruct;
	CanIo_Config();
	CAN_ClockCmd();
	CAN_DeInit(CAN1);
	
#if (CAN_FILTER_MODE == CAN_Filter_List)
	Can_FilterListModeConfig();
#elif(CAN_FILTER_MODE == CAN_Filter_Mask)
  for(u8 i=0; i<CANID_Number; i++)
	{
		Can_FilterMaskModeConfig(i,CAN_Filter_FIFO0,u32CanId_Array[i]);
	}
#else
	Can_FilterMaskModeConfig(0,CAN_Filter_FIFO0,u32CanId_Array[0]);
#endif
	CAN_InitStruct.CAN_ABOM = DISABLE;
	CAN_InitStruct.CAN_AWUM = DISABLE;
	CAN_InitStruct.CAN_NART = DISABLE;
	CAN_InitStruct.CAN_RFLM = DISABLE;
	CAN_InitStruct.CAN_TTCM = DISABLE;
	CAN_InitStruct.CAN_TXFP = DISABLE;
	CAN_InitStruct.CAN_Mode = CAN_Mode_Normal;
	CAN_InitStruct.CAN_SJW = CAN_SJW_4tq;
	CAN_InitStruct.CAN_BS1 = CAN_BS1_13tq;
	CAN_InitStruct.CAN_BS2 = CAN_BS2_4tq;
	u8NTq = 1+CAN_InitStruct.CAN_BS1+1+CAN_InitStruct.CAN_BS2+1;
	CAN_InitStruct.CAN_Prescaler = (u16)(CAN_ClockFreq*1000/CAN_Baud/u8NTq);
	CAN_Init(CAN1,&CAN_InitStruct);
	
	Nvic_CanConfig();
	
	CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);
}



